package chapter7;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author caiya
 * @date 2020/3/31 21:33
 */
@Slf4j
public class CountDownLatchTest {
    static volatile CountDownLatch countDownLatch = new CountDownLatch(2);

    public static void main(String[] args) throws InterruptedException {
        /**
         * CountDownLatch：线程同步器
         * 1、CountDownLatch和join的区别：
         *      1）join会导致调用线程阻塞挂起直到线程执行结束，而CountDownLatch允许在线程执行的任意时刻进行计数递减
         *      2）一般使用线程池的时候没法使用join，就必须使用CountDownLatch
         * 2、CountDownLatch底层使用AQS实现，计数变量使用AQS的state表示
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    log.debug(Thread.currentThread().getName());
                }finally {
                    // 计数递减
                    countDownLatch.countDown();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    log.debug(Thread.currentThread().getName());
                }finally {
                    // 计数递减
                    countDownLatch.countDown();
                }
            }
        }).start();

        // 等待线程执行结束
        countDownLatch.await();
        log.debug(Thread.currentThread().getName() + " is over!");

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 6, 60L, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.CallerRunsPolicy());


        countDownLatch = new CountDownLatch(2);

        threadPoolExecutor.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    log.debug(Thread.currentThread().getName());
                }finally {
                    // 计数递减
                    countDownLatch.countDown();
                }
            }
        });

        threadPoolExecutor.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    log.debug(Thread.currentThread().getName());
                }finally {
                    // 计数递减
                    countDownLatch.countDown();
                }
            }
        });

        countDownLatch.await();
        log.debug(Thread.currentThread().getName() + " is over!");

        threadPoolExecutor.shutdown();
    }

}
